//
//  WebController.swift
//  SeeFM_Swift
//
//  Created by CBCT_MBP on 2021/7/6.
//

import UIKit
import WebKit

class WebController: SFBaseController {

    var webView: WKWebView?
    var progressView: WebProgressView?

    fileprivate var loadProgress: CGFloat = 0.0
    fileprivate var timer: DispatchSourceTimer?
    var firstLoadURL: URL?
    var loadingURL: URL?

    var url: URL?

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .default
    }

    init(_ url: String, title: String? = nil) {
        super.init(nibName: nil, bundle: nil)
        self.url = URL.init(string: url)
        self.title = title
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    fileprivate func startWebLoadProgress() {
        stopTimer()
        loadProgress = 0.4
        timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)
        timer!.schedule(deadline: .now(), repeating: .milliseconds(100))
        timer!.setEventHandler(handler: { [weak self] in
            DispatchQueue.main.async {
                self?.addWebViewLoadProgress()
            }
        })
        timer!.resume()
    }

    fileprivate func addWebViewLoadProgress() {
        let step: CGFloat = 0.1
        if loadProgress < 0.8 {
            loadProgress += step
        }
        progressView?.progress = loadProgress
    }

    fileprivate func stopWebViewLoadProgress() {
        progressView?.progress = 1
        stopTimer()
    }

    fileprivate func stopTimer() {
        timer?.cancel()
        timer = nil
    }

    func addWKWebView() {
        
        let config = WKWebViewConfiguration()
        let preference = WKPreferences()
        config.preferences = preference
        config.allowsInlineMediaPlayback = true

        let contentController = WKUserContentController()
        config.userContentController = contentController

        let webView = WKWebView(frame: .zero)
        webView.isOpaque = false
        webView.backgroundColor = UIColor.white
        webView.allowsBackForwardNavigationGestures = true

        webView.autoresizingMask = [UIView.AutoresizingMask.flexibleWidth, UIView.AutoresizingMask.flexibleHeight]
        webView.scrollView.delegate = self
        webView.navigationDelegate = self
        self.view.addSubview(webView)
        self.webView = webView
        webView.snp.makeConstraints { (make) in
            make.left.right.bottom.equalToSuperview()
            make.top.equalTo(Adapter.Screen.topHeight)
        }

        progressView = WebProgressView(frame: .zero)
        self.view.addSubview(progressView!)
        progressView?.snp.makeConstraints({ (make) in
            make.left.equalToSuperview()
            make.top.equalTo(Adapter.Screen.topHeight)
            make.height.equalTo(2)
        })
    }

    override open func viewDidLoad() {
        super.viewDidLoad()

        addWKWebView()

        if let url = self.url {
            loadURL(url)
        }
    }

    open func loadURL(_ url: URL) {
        let timeoutInterval: TimeInterval = 60
        var request = URLRequest(url: url, cachePolicy: .useProtocolCachePolicy, timeoutInterval: timeoutInterval)
        loadRequest(&request)
    }

    open func loadRequest(_ request: inout URLRequest) {
        self.webView?.load(request)
    }

    deinit {
        stopWebViewLoadProgress()
        webView?.stopLoading()
        webView?.navigationDelegate = nil
        webView?.scrollView.delegate = nil
    }
}


// MARK: WKNavigationDelegate
extension WebController: WKNavigationDelegate {

    public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Swift.Void) {
        self.loadingURL = nil
        self.loadingURL = navigationAction.request.url

        //如果是映射到本地可以处理的url decisionHandler(.cancel)
        if navigationAction.targetFrame == nil {
            webView.load(navigationAction.request)
        }

        decisionHandler(.allow)

    }

    public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        startWebLoadProgress()
    }

    public func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {

    }

    public func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        stopWebViewLoadProgress()
        self.loadingURL = nil
        SVProgressHUD.showError(withStatus: "页面加载失败")
    }

    public func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {

    }

    public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        stopWebViewLoadProgress()
        var title: String = self.title ?? ""
        if title.isEmpty {
            title = webView.title ?? ""
        }
        if title.count > 10 {
            title = String(title[title.startIndex..<title.index(title.startIndex, offsetBy: 10)])
            title += "..."
        }
        self.title = title

        self.loadingURL = nil
    }

    public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        stopWebViewLoadProgress()
        self.loadingURL = nil
    }

    public func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Swift.Void) {
        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            if let trust = challenge.protectionSpace.serverTrust {
                let card = URLCredential(trust: trust)
                completionHandler(.useCredential, card)
            }
        }
    }

    public func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
        webView.reload()
    }
}


// MARK: WKUIDelegate
extension WebController: WKUIDelegate {
    public func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Swift.Void) {
        // js 里面的alert实现，如果不实现，alert函数无效

        let alertController = UIAlertController(title: "提示", message: message, preferredStyle: .alert)
        let confirmAction = UIAlertAction(title: "确定", style: .default) { (_) in
            completionHandler()
        }
        alertController.addAction(confirmAction)

    }

    public func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Swift.Void) {
        let alertController = UIAlertController(title: "提示", message: message, preferredStyle: .alert)
        let confirmAction = UIAlertAction(title: "确定", style: .default) { (_) in
            completionHandler(true)
        }
        let cancelAction = UIAlertAction(title: "取消", style: .cancel) { (_) in
            completionHandler(true)
        }
        alertController.addAction(confirmAction)
        alertController.addAction(cancelAction)

    }

    public func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Swift.Void) {
        completionHandler("Client Not handler")
    }

}


extension WebController: UIScrollViewDelegate {
    //类似native的加速滑动效果
    public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        scrollView.decelerationRate = UIScrollView.DecelerationRate.normal
    }
}

